package com.jeeplus.module.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeeplus.common.pojo.BaseService;
import com.jeeplus.common.pojo.Page;
import com.jeeplus.module.system.entity.Traceline;
import com.jeeplus.module.system.mapper.TracelineMapper;
import com.jeeplus.module.system.service.ITracelineService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author housaileipaginationInterceptor
 * @since 2019-05-23
 */
@Service
public class TracelineServiceImpl extends BaseService<TracelineMapper, Traceline> implements ITracelineService {

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public Page<Traceline> pageConditions(Page inPage) throws Exception {
        Page<Traceline> page = new Page<>(inPage.getCurrent(), inPage.getSize());
        List<Traceline> tracelineList = baseMapper.page(page);
        for (Traceline traceline : tracelineList) {
            Traceline traceline1 = new Traceline();
            traceline1.setId(traceline.getId());
            if (traceline.getWayPointLat() == null) {
                HashMap geocode = this.geocode(traceline.getWayPointAddress());
                if ((Boolean) (geocode.get("stat"))) {
                    String[] geocodeSplit = ((String) geocode.get("location")).split(",");
                    traceline1.setWayPointLat(geocodeSplit[0]);
                    traceline1.setWayPointLng(geocodeSplit[1]);
                    traceline1.setSyncStatus("YES");
                } else {
                    traceline1.setSyncStatus((String) geocode.get("info"));
                }
            } else {
                traceline1.setSyncStatus("YES");
            }
            baseMapper.updateById(traceline1);
        }
        page.setRecords(tracelineList);
        return page;
    }

    @Override
    public Page<Traceline> pageTraceLineConditions(Page inPage) throws Exception {
        Page<Traceline> page = new Page<>(inPage.getCurrent(), inPage.getSize());
        List<Traceline> tracelineList = baseMapper.page(page);
        for (Traceline traceline : tracelineList) {
            Traceline traceline1 = new Traceline();
//            traceline1.setId(traceline.getId());
            traceline1.setWayPointLat(traceline.getWayPointLat());
            traceline1.setWayPointLng(traceline.getWayPointLng());
            traceline1.setToLat(traceline.getToLat());
            traceline1.setToLng(traceline.getToLng());
            if (traceline.getWayPointLat() != null && traceline.getWayPointLng() != null && traceline.getToLat() != null && traceline.getToLng() != null) {
                HashMap geocode = this.geocodeTraceLine(traceline.getWayPointLat() + "," + traceline.getWayPointLng(), traceline.getToLat() + "," + traceline.getToLng());
                if ((Boolean) (geocode.get("stat"))) {
                    String polyline = ((String) geocode.get("polyline"));
                    traceline1.setTraceLine(polyline);
                    traceline1.setSyncStatus("YES");
                } else {
                    traceline1.setSyncStatus((String) geocode.get("info"));
                }
            } else {
                traceline1.setSyncStatus("YES");
            }
            baseMapper.updateByPoint(traceline1);
        }
        page.setRecords(tracelineList);
        return page;
    }

    @Override
    public Page<Traceline> pageTraceLineSampling(Page inPage, int samplingRate,long lessthan,long bigthan) throws Exception  {
        Page<Traceline> page = new Page<>(inPage.getCurrent(), inPage.getSize());
        List<Traceline> tracelineList = baseMapper.pageSampling(page,lessthan,bigthan);
        for (Traceline traceline : tracelineList) {
            Traceline traceline1 = new Traceline();
//            traceline1.setId(traceline.getId());
            traceline1.setWayPointLat(traceline.getWayPointLat());
            traceline1.setWayPointLng(traceline.getWayPointLng());
            traceline1.setToLat(traceline.getToLat());
            traceline1.setToLng(traceline.getToLng());

            String tracelineString = traceline.getTraceLine();
            String[] tracelineStringSplit = StringUtils.split(tracelineString,";");
            int newTracelineStringSize = tracelineStringSplit.length / samplingRate;
            String[] newTracelineString = new String[newTracelineStringSize+1];
            for (int i = 0; i < newTracelineStringSize; i++) {
                newTracelineString[i] = tracelineStringSplit[i * samplingRate];
            }
            newTracelineString[newTracelineStringSize] = tracelineStringSplit[tracelineStringSplit.length-1];
            String joinString = StringUtils.join(newTracelineString, ";");
            traceline1.setSampling(joinString);
            traceline1.setSyncStatus("YES");

            baseMapper.updateByPointAndSampling(traceline1);
        }
        page.setRecords(tracelineList);
        return page;
    }

    public HashMap geocode(String address) {
        String forObject = restTemplate.getForObject("https://restapi.amap.com/v3/geocode/geo?address=" + address + "&output=json&key=b9b9b9c7d3f529da15e50540d84ebbc4", String.class);
        JSONObject jsonObject = JSON.parseObject(forObject);
        HashMap result = new HashMap();

        if (jsonObject.getString("status").equals("1")) {
            JSONArray locationArray = jsonObject.getJSONArray("geocodes");
            if (locationArray != null && locationArray.size() > 0) {
                String location = locationArray.getJSONObject(0).getString("location");
                result.put("stat", true);
                result.put("location", location);
            } else {
                System.out.println("------------------000000000000000000-------------------------" + jsonObject.toJSONString());
                result.put("stat", false);
                result.put("info", "UNKNOWN");
            }
        } else {
            System.out.println("------------------000000000000000000-------------------------" + jsonObject.toJSONString());
            result.put("stat", false);
            result.put("info", jsonObject.getString("info"));
        }
        return result;
    }

    public HashMap geocodeTraceLine(String waypoint, String to) {
        String url = "https://restapi.amap.com/v3/direction/driving?origin=" + waypoint + "&destination=" + to + "&extensions=all&output=json&key=b9b9b9c7d3f529da15e50540d84ebbc4";
        String forObject = null;
        JSONObject jsonObject = null;
        HashMap result = new HashMap();
        try {
            forObject = restTemplate.getForObject(url, String.class);
            jsonObject = JSON.parseObject(forObject);

        } catch (RestClientException e) {
            result.put("stat", false);
            result.put("info", "ERROR");
            return result;
        }


        if (jsonObject.getString("status").equals("1")) {
            JSONArray paths = jsonObject.getJSONObject("route").getJSONArray("paths");
            if (paths != null && paths.size() > 0) {
                JSONArray steps = paths.getJSONObject(0).getJSONArray("steps");
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < steps.size(); i++) {
                    if (i == 0) {
                        sb.append(steps.getJSONObject(i).getString("polyline"));
                    } else {
                        sb.append(";");
                        sb.append(steps.getJSONObject(i).getString("polyline"));
                    }
                }
                result.put("stat", true);
                result.put("polyline", sb.toString());
            } else {
                result.put("stat", false);
                result.put("info", "UNKNOWN");
            }
        } else {
            System.out.println("------------------000000000000000000-------------------------" + jsonObject.toJSONString());
            System.out.println(url);
            result.put("stat", false);
            result.put("info", jsonObject.getString("info"));
        }
        return result;
    }

}
